<?php

namespace app\service;

use app\enum\UserCode;
use app\model\User;
use app\model\UserProp;
use GuzzleHttp\Client;
use support\exception\BusinessException;
use support\Request;
use Tinywan\Jwt\JwtToken;


class UserService extends Base
{
    //登录
    public function toLoginByCode($code, $platform): array
    {

        $userModel = new User();
        //获取微信小程序的openid
        if ($platform) {
            $openid = $this->get_openid($code);
        } else {
            $openid = $code;
        }
        //查询会员信息
        $userInfo = $userModel->where(['code' => $openid])->find();
        if (empty($userInfo)) {
            //注册
            $param = [
                'code' => $openid,
                'nickname' => $data['nickname'] ?? 'wx_' . rand(1000, 10000),
                'avatar' => $data['avatar'] ?? '',
                'platform' => $platform,
                'status' => UserCode::STATUS_NORMAL,
            ];

            $id = $userModel->insertGetId($param);
            if (!$id) {
                return apiError('注册失败');
            }
            //注册成功
            $userInfo = $userModel->where(['id' => $id])->find();

        }


        return $this->extracted($userInfo);

    }


    //通过手机号和验证码登录/注册
    public function toLoginByMobileAndSmsCode($mobile, $sms_code,$platform): array
    {
        $user = User::where('mobile', $mobile)->find();
        if (!$user) {
            //注册
            $param = [
                'mobile' => $mobile,
                'nickname' => $data['nickname'] ?? 'mobile_' . rand(1000, 10000),
                'avatar' => $data['avatar'] ?? '',
                'platform' => $platform,
                'status' => UserCode::STATUS_NORMAL,
            ];

            $id = $user->insertGetId($param);
            if (!$id) {
                return apiError('注册失败');
            }
            //注册成功
            $user = $user->where(['id' => $id])->find();
        }
        //验证验证码
        if ($sms_code != '123456') {
            return apiError('验证码错误');
        }
        return $this->extracted($user);
    }

    //获取微信小程序的openid
    protected function get_openid($js_code)
    {
        $appid = env('wx.appId', '');
        $secret = env('wx.appSecret', '');
        //改成
        //创建一个有基本URI的客户端
        $client = new Client();
        //发送请求
        $response = $client->request('GET', 'https://api.weixin.qq.com/sns/jscode2session?appid='. $appid . '&secret='. $secret . '&js_code='. $js_code . '&grant_type=authorization_code');
        //获取返回数据
        $data = json_decode($response->getBody(), true);
        if (isset($data['openid'])) {
            return $data['openid'];
        }
        return $response;
    }

    //修改问题答案
    public function modify_problem_answer(User $user,$problem,$answer)
    {
        $user->problem = $problem;
        $user->answer = $answer;
        $user->save();
        return apiSuccess($user);
    }


    //修改用户信息
    public function change_score(User $user, int $score, int $type)
    {

        switch ($type) {
            case 1:
                $user->score += $score;
                break;
            case 2:
                $user->score -= $score;
                if ($user->score < 0) {
                    return apiError('积分不足');
                }
                break;
            default:
                return apiError('类型错误');
        }

        $user->save();
        return apiSuccess($user);
    }

    //修改用户昵称
    function update_nickname(User $user, $nickname)
    {
        $user->nickname = $nickname;
        $user->save();
        return apiSuccess($user);
    }


    //我的背包
    public function backpack(User $user)
    {
        $props = UserProp::where('user_id', $user->id)->where('num', '>', 0)->select();
        return apiSuccess($props);
    }


    /**
     * 注册、登录成功后返回用户信息
     * @param User $userInfo
     * @return array
     */
    private function extracted(User $userInfo): array
    {
        if ($userInfo['status'] == UserCode::STATUS_DISABLE) {
            return apiError('该账号已停用');
        }

        $extend = [
            'id' => $userInfo['id'],
            'name' => '模版',
            'access_exp' => 8640000,  // 100天
            'refresh_exp' => 8640000,  // 100天
            'client' => JwtToken::TOKEN_CLIENT_MOBILE
        ];
        $generateToken = JwtToken::generateToken($extend);

        if ($generateToken) {
            $data = ['token' => $generateToken['access_token'], 'user_info' => $userInfo];
            return apiSuccess($data);
        }
        return apiError('失败');
    }

    //上传语音
    public function upload_voice(User $user,Request $request)
    {

        $file = current($request->file());
        if (!$file || !$file->isValid()) {
            return apiError('上传失败');
        }
        $data = $this->base($request, '/upload/files/' . date('Ymd'));
        return apiSuccess([
            'url' => $data['url'],
            'name' => $data['name'],
            'size' => $data['size'],
        ]);
    }

    protected function base(Request $request, $relative_dir): array
    {
        $relative_dir = ltrim($relative_dir, '\\/');
        $file = current($request->file());
        if (!$file || !$file->isValid()) {
            throw new BusinessException('未找到上传文件', 400);
        }

        $admin_public_path = rtrim(config('plugin.admin.app.public_path', ''), '\\/');
        $base_dir = $admin_public_path ? $admin_public_path . DIRECTORY_SEPARATOR : base_path() . '/plugin/admin/public/';
        $full_dir = $base_dir . $relative_dir;
        if (!is_dir($full_dir)) {
            mkdir($full_dir, 0777, true);
        }

        $ext = $file->getUploadExtension() ?: null;
        $mime_type = $file->getUploadMimeType();
        $file_name = $file->getUploadName();
        $file_size = $file->getSize();

        if (!$ext && $file_name === 'blob') {
            [$___image, $ext] = explode('/', $mime_type);
            unset($___image);
        }

        $ext = strtolower($ext);
        $ext_forbidden_map = ['php', 'php3', 'php5', 'css', 'js', 'html', 'htm', 'asp', 'jsp'];
        if (in_array($ext, $ext_forbidden_map)) {
            throw new BusinessException('不支持该格式的文件上传', 400);
        }

        $relative_path = $relative_dir . '/' . bin2hex(pack('Nn', time(), random_int(1, 65535))) . ".$ext";
        $full_path = $base_dir . $relative_path;
        $file->move($full_path);
        $image_with = $image_height = 0;
        if ($img_info = getimagesize($full_path)) {
            [$image_with, $image_height] = $img_info;
            $mime_type = $img_info['mime'];
        }
        return [
            'url' => "/app/admin/$relative_path",
            'name' => $file_name,
            'realpath' => $full_path,
            'size' => $file_size,
            'mime_type' => $mime_type,
            'image_with' => $image_with,
            'image_height' => $image_height,
            'ext' => $ext,
        ];
    }



}